package es.ucm.fdi.healthpred.controlador.utils.connection;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import es.ucm.fdi.healthpred.controlador.excepciones.ExcepcionConexion;

/**
 * Implementaci&oacute;n del patr&oacute;n <i>Singleton</i> para obtener una
 * conexi&oacute;n &uacute;nica a la BD de manera est&aacute;tica.
 * 
 * @since 1.0
 * 
 * @version 1.0
 * 
 * @author &Aacute;lvaro G&oacute;mez Porris
 * @author V&iacute;ctor L&oacute;pez Monte
 * @author Carlos Rodr&iacute;guez Colliga
 * 
 */
public class SingletonConnectionManager {

	private static SingletonConnectionManager _uniqueInstance = null;
	private Configuration configuration;
	private Session session;
	private SessionFactory sessionFactory;

	/**
	 * @return La instancia de conexi&oacute;n &uacute;nica.
	 */
	public static SingletonConnectionManager getInstance() {
		if (_uniqueInstance == null) {
			_uniqueInstance = new SingletonConnectionManager();
		}
		return _uniqueInstance;
	}

	/**
	 * @return La sesi&oacute;n.
	 * @throws ExcepcionConexion
	 */
	public Session getSession() throws ExcepcionConexion {
		// [3.1] La crea si es nula o cerrada
		if (session == null || !session.isOpen()) {
			try {
				session = getSessionFactory().openSession();
			} catch (ExcepcionConexion e) {
				throw e;
			}
		}
		return session;
	}

	/**
	 * Pone a null la sesi&oacute;n actual
	 * 
	 * @see Session
	 */
	public void setSessionNull() {
		session = null;
	}

	/* PRIVADOS */
	/**
	 * @return
	 * @throws ExcepcionConexion
	 */
	private Configuration getConfiguration() throws ExcepcionConexion {
		if (configuration == null) {
			try {
				configuration = new Configuration();
				configuration.configure("hibernateHealthpred.cfg.xml");
			} catch (Throwable e) {
				throw new ExcepcionConexion(e);
			}
		}
		return configuration;
	}

	/**
	 * @return
	 * @throws ExcepcionConexion
	 */
	private SessionFactory getSessionFactory() throws ExcepcionConexion {
		if (sessionFactory == null) {
			try {
				sessionFactory = getConfiguration().buildSessionFactory();
			} catch (ExcepcionConexion e) {
				throw e;
			}
		}
		return sessionFactory;
	}

}